<template>
  <div
    class="qrcode-template-container"
    @click.stop="onItemSelected"
    @mouseenter="onMouseEnter"
    @mouseover="onMouseOver"
    @mouseleave="onMouseLeave"
    :style="{
      width: ui.clientWidth + 'px',
      height: ui.clientHeight + 'px'
    }"
  >
    <slot></slot>
    <!-- 选中状态 -->
    <div class="outline" :style="outline_style">
      <div class="outline-block">
        <span class="left-top"></span>
        <span class="right-top"></span>
        <span class="right-bottom"></span>
        <span class="left-bottom"></span>
      </div>
    </div>
    <!-- 悬浮状态 -->
    <div v-if="isHoverOutlineShow" class="hover-ouline" :style="hover_outline_style"></div>
  </div>
</template>

<script lang="ts">
import { Message } from 'element-ui'
import Vue from 'vue'
import { Component, Emit, Ref } from 'vue-property-decorator'
import { Dictionary } from 'vue-router/types/router'
@Component
class QrTemplate extends Vue {
  @Ref() outline_canvas!: HTMLCanvasElement
  outline_style: Dictionary<string> = {}
  ui: Dictionary<number> = {
    clientWidth: 600,
    clientHeight: 400
  }
  isHoverOutlineShow: boolean = false
  hover_outline_style: Dictionary<string> = {}
  selectedDom!: any
  mounted() {
    window.addEventListener('resize', () => {
      this.computeOutlinePosition()
    })
    this.$broadOn('dom_be_edited', () => {
      this.$nextTick(() => {
        this.computeOutlinePosition()
      })
    })
    // 获取插槽内节点的尺寸
    this.$nextTick(() => {
      const slot_dom = this.$slots.default
      if (slot_dom === undefined) {
        Message({
          message: '未找到模板节点，请先选择',
          type: 'warning'
        })
        return
      }
      const { clientWidth, clientHeight } = slot_dom[0].elm as any
      this.ui = {
        clientWidth,
        clientHeight
      }
    })
  }
  @Emit()
  onItemSelected(e: any) {
    this.selectedDom = e.target
    this.computeOutlinePosition()
    return e.target
  }
  onMouseEnter() {
    this.isHoverOutlineShow = true
  }
  onMouseOver(e: any) {
    const { width, height, top, left } = e.target.getBoundingClientRect()
    this.hover_outline_style = {
      width: width - 2 + 'px',
      height: height - 2 + 'px',
      top: top - 1 + 'px',
      left: left - 1 + 'px'
    }
  }
  onMouseLeave() {
    this.isHoverOutlineShow = false
  }
  computeOutlinePosition() {
    if (!this.selectedDom) return
    const { width, height, top, left } = this.selectedDom.getBoundingClientRect()
    this.outline_style = {
      width: width + 2 + 'px',
      height: height + 2 + 'px',
      top: top - 1 + 'px',
      left: left - 1 + 'px'
    }
  }
}
export default QrTemplate
</script>

<style lang="less" scoped>
@import '~@/styles/theme.less';
.qrcode-template-container {
  margin: 60px;
  /* 声明一个容器 */
  background-color: #ffffff;
  overflow: hidden;
  .item {
    box-sizing: border-box;
    text-align: center;
    font-size: 16px;
    color: #fff;
    background-color: #ffffff;
    cursor: pointer;
  }
  .title {
    grid-area: title;
  }
  .message {
    grid-area: message;
  }
  .qrcode {
    grid-area: qrcode;
  }
}
.outline {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  pointer-events: none;
  .outline-block {
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    position: relative;
    border: solid 2px;
    #color(border-color, --point-blue-color);
    span {
      position: absolute;
      width: 5px;
      height: 5px;
      border: solid 1px;
      #color(border-color, --point-blue-color);
      #color(background-color, --module-bg-color);
    }
    .left-top {
      left: 0;
      top: 0;
      transform: translate(-50%, -50%);
    }
    .right-top {
      right: 0;
      top: 0;
      transform: translate(50%, -50%);
    }
    .right-bottom {
      right: 0;
      bottom: 0;
      transform: translate(50%, 50%);
    }
    .left-bottom {
      left: 0;
      bottom: 0;
      transform: translate(-50%, 50%);
    }
  }
}
.hover-ouline {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  pointer-events: none;
  border: solid 2px #008cff;
}
</style>
